/**
 * 亚马逊德国爬虫任务
 */

// 引入数据库模块
const dbConnection = require('../../db/connection');
const CrawlResult = require('../../db/models/CrawlResult');
const Review = require('../../db/models/Review');

// 引入图片下载所需模块
const axios = require('axios');
const fs = require('fs');
const path = require('path');

module.exports = {
    // 任务名称
    name: 'amazon-jp',
    
    // 是否启用此任务
    enabled: true,
    
    // 目标网站URL
    // url: 'https://www.amazon.co.jp',
    url: 'https://www.amazon.co.jp',
    
    // 搜索配置（可选）
    search: {
        url: 'https://www.amazon.co.jp/s',
        selectors: {
            searchInput: '#twotabsearchtextbox',
            searchButton: '#nav-search-submit-button',
        }
    },
    
    // 页面元素选择器（可选）
    selectors: {
        productList: '.s-result-item',
        productTitle: 'h2 .a-link-normal',
        productPrice: '.a-price-whole',
        productImage: '.s-image',
        productLink: 'h2 .a-link-normal',
        productRating: '.a-icon-star-small',
    },
    
    // 爬取选项
    crawlOptions: {
        maxPages: 5,
        delayBetweenPages: 2000,
        waitForSelector: '.s-result-item',
        timeout: 30000
    },
    
    /**
     * 切换网站语言
     * @param {Page} page - Playwright页面对象
     * @param {string} langCode - 语言代码（如 "en", "de", "cs", "nl", "pl", "tr", "da"）
     * @returns {Promise<boolean>} 是否成功切换语言
     */
    async switchLanguage(page, langCode = 'en') {
        try {
            console.log(`   正在切换语言到: ${langCode.toUpperCase()}...`);
            
            // 语言代码映射（小写代码 -> 完整的语言标识）
            const langMap = {
                'jp': 'ja_JP',
                'en': 'en_US',
                'zh': 'zh_CN'
            };
            
            const fullLangCode = langMap[langCode.toLowerCase()] || langMap['en'];
            console.log(`   目标语言标识: ${fullLangCode}`);
            
            // 查找语言选择器（DE 按钮）- 可能需要根据实际页面调整选择器
            const languageButton = await page.$('#icp-nav-flyout');
            
            if (!languageButton) {
                console.log(`   ⚠️  未找到语言选择按钮`);
                return false;
            }
            
            // 鼠标移动到 DE 元素上，触发下拉菜单
            console.log(`   移动鼠标到语言选择器...`);
            await languageButton.hover();
            await page.waitForTimeout(1000); // 等待下拉菜单出现
            
            // 等待下拉菜单显示
            const flyoutMenu = await page.$('#nav-flyout-icp');
            if (!flyoutMenu) {
                console.log(`   ⚠️  下拉菜单未出现`);
                return false;
            }
            
            console.log(`   ✅ 下拉菜单已显示`);
            
            // 查找并点击对应语言的链接
            const languageLink = await page.$(`a[href="#switch-lang=${fullLangCode}"]`);
            if (languageLink) {
                console.log(`   ✅ 找到语言选项，准备点击...`);
                await languageLink.click();
                await page.waitForTimeout(2000); // 等待页面刷新
                
                // 点击确认按钮（ショッピングを続ける）返回原页面
                try {
                    console.log(`   ⏳ 等待确认按钮出现...`);
                    const confirmButton = await page.waitForSelector('button.a-button-text[alt="ショッピングを続ける"]', {
                        timeout: 5000,
                        visible: true
                    });
                    if (confirmButton) {
                        console.log(`   ✅ 找到确认按钮，准备点击...`);
                        await confirmButton.click();
                        await page.waitForTimeout(2000); // 等待返回原页面
                        console.log(`   ✅ 已点击确认按钮，返回原页面`);
                    }
                } catch (error) {
                    console.log(`   ⚠️  未找到确认按钮，可能已经在目标页面: ${error.message}`);
                }
                
                console.log(`   ✅ 语言已切换到 ${langCode.toUpperCase()}`);
                return true;
            } else {
                console.log(`   ⚠️  未找到语言选项: ${fullLangCode}`);
                return false;
            }
        } catch (error) {
            console.log(`   ⚠️  切换语言时出错: ${error.message}`);
            return false;
        }
    },

    /**
     * 处理Cookie同意按钮
     * @param {Page} page - Playwright页面对象
     * @returns {Promise<boolean>} 是否成功点击了按钮
     */
    async handleCookieConsent(page) {
        try {
            console.log(`   正在检测Cookie同意按钮...`);
            const cookieButton = await page.$('#sp-cc-accept');
            
            if (cookieButton) {
                console.log(`   ✅ 找到Cookie按钮，准备点击...`);
                await cookieButton.click();
                await page.waitForTimeout(1000); // 等待点击完成
                console.log(`   ✅ Cookie按钮已点击`);
                return true;
            } else {
                console.log(`   ℹ️  未找到Cookie按钮，继续执行...`);
                return false;
            }
        } catch (error) {
            console.log(`   ⚠️  处理Cookie按钮时出错: ${error.message}`);
            return false;
        }
    },

    /**
     * 处理海外地址确认弹窗（包括确认后的提示框关闭）
     * @param {Page} page - Playwright页面对象
     * @returns {Promise<boolean>} 是否成功处理了地址确认
     */
    async handleAddressConfirmation(page) {
        try {
            console.log(`   正在检测海外地址确认按钮...`);
            
            // 使用 XPath 查找地址确认按钮
            const addressButton = await page.$('xpath=/html/body/div[1]/header/div/div[2]/div[2]/div/div[3]/span[1]/span/input');
            
            if (addressButton) {
                console.log(`   ✅ 找到地址确认关闭按钮，准备点击...`);
                await addressButton.click();
                await page.waitForTimeout(1500); // 等待点击完成
                console.log(`   ✅ 地址确认按钮已点击`);
                
                // 点击地址确认后，关闭弹出的提示框
                console.log(`   正在检测弹出提示框关闭按钮...`);
                const closeButton = await page.$('button[data-action="a-popover-close"]');
                
                if (closeButton) {
                    console.log(`   ✅ 找到提示框关闭按钮，准备点击...`);
                    await closeButton.click();
                    await page.waitForTimeout(1000); // 等待弹窗关闭
                    console.log(`   ✅ 提示框已关闭`);
                } else {
                    console.log(`   ℹ️  未找到提示框关闭按钮，继续执行...`);
                }
                
                return true;
            } else {
                console.log(`   ℹ️  未找到地址确认按钮，继续执行...`);
                return false;
            }
        } catch (error) {
            console.log(`   ⚠️  处理地址确认时出错: ${error.message}`);
            return false;
        }
    },

    /**
     * 自定义爬取逻辑
     * @param {Page} page - Playwright页面对象
     * @param {EcommerceCrawler} crawler - 爬虫实例
     * @returns {Object} 爬取结果
     */
    async customCrawl(page, crawler) {
        console.log(`🎯 正在爬取【${this.name}】...`);
        
        try {
            // 打开亚马逊德国首页
            console.log(`   正在打开页面: ${this.url}`);
            await page.goto(this.search.url, {
                waitUntil: 'load',
                timeout: this.crawlOptions.timeout
            });
            // 等待页面加载
            await page.waitForTimeout(3000);
            
            // 处理Cookie同意按钮
            await this.handleCookieConsent(page);
            
            // 处理海外地址确认弹窗（包括确认后的提示框关闭）
            await this.handleAddressConfirmation(page);
            
            // 切换语言（如果需要）
            await this.switchLanguage(page, 'en'); // 可选：en, de, cs, nl, pl, tr, da
            
            //开始搜索商品
            // 优先级：环境变量 > 配置文件 > 默认值
            let keyword = process.env.CRAWL_KEYWORD;
            
            if (!keyword) {
                // 从配置文件读取第一个关键词作为默认值
                const config = require('../../tasks.config');
                const keywords = config.keywords && config.keywords['amazon-de'];
                keyword = (keywords && keywords.length > 0) ? keywords[0] : 'Baby Foods';
            }
            
            console.log(`   🔍 搜索关键词: ${keyword}`);
            await this.searchProducts(page, keyword);

            // 处理所有分页（endPage: null 表示处理到真正的最后一页）
            // maxRetries: 每页最多重试次数，retryDelay: 重试前等待时间（毫秒）
            await this.handlePagination(page, this.processSinglePage.bind(this), { 
                startPage: 1, 
                endPage: null,
                maxRetries: 3,      // 最多重试 3 次
                retryDelay: 5000    // 重试前等待 5 秒
            });
            
            // 获取页面信息
            const title = await page.title();
            const url = page.url();
            
            console.log(`   页面标题: ${title}`);
            console.log(`   页面URL: ${url}`);
            
            // // 尝试提取页面上的主要分类或推荐商品
            // const categories = await page.$$eval('.nav-a', (elements) => {
            //     return elements.slice(0, 10).map(el => ({
            //         text: el.textContent?.trim(),
            //         href: el.href
            //     })).filter(item => item.text && item.text.length > 0);
            // }).catch(() => []);
            
            // console.log(`   找到 ${categories.length} 个导航分类`);
            
            // 等待一段时间，方便调试（不立即关闭网页）
            // console.log(`   ⏸️  等待用于调试，页面将保持打开状态...`);
            // await page.waitForTimeout(3000000); // 等待 30 秒
            // console.log(`   ✅ 调试等待结束`);
            
            // 返回爬取结果
            return {
                success: true,
                url: url,
                title: title,
                timestamp: new Date().toISOString(),
                data: {
                    pageType: 'homepage',
                    // categories: categories,
                    country: 'Germany',
                    currency: 'EUR',
                    language: 'de'
                }
            };
            
        } catch (error) {
            console.error(`❌ 爬取【${this.name}】失败:`, error.message);
            // console.log('错误调试');
            // await page.waitForTimeout(3000000); // 等待 30 秒
            // console.log(`   ✅ 调试等待结束`);
            return {
                success: false,
                error: error.message,
                timestamp: new Date().toISOString()
            };
        }
    },
    
    /**
     * 获取分页信息
     * @param {Page} page - Playwright页面对象
     * @returns {Object} 分页信息 {currentPage, totalPages}
     */
    async getPaginationInfo(page) {
        try {
            const paginationInfo = await page.evaluate(() => {
                // 获取当前页
                const currentPageElement = document.querySelector('.s-pagination-item.s-pagination-selected');
                const currentPage = currentPageElement ? parseInt(currentPageElement.textContent.trim()) : 1;
                
                // 获取总页数 - 查找所有分页按钮，找到最大的数字
                const allPageElements = Array.from(document.querySelectorAll('.s-pagination-item'));
                let totalPages = 1;
                
                allPageElements.forEach(el => {
                    const pageNum = parseInt(el.textContent.trim());
                    if (!isNaN(pageNum) && pageNum > totalPages) {
                        totalPages = pageNum;
                    }
                });
                
                return { currentPage, totalPages };
            });
            
            return paginationInfo;
        } catch (error) {
            console.log(`   ⚠️  获取分页信息失败: ${error.message}`);
            return { currentPage: 1, totalPages: 1 };
        }
    },

    /**
     * 点击下一页
     * @param {Page} page - Playwright页面对象
     * @returns {Promise<boolean>} 是否成功翻页
     */
    async goToNextPage(page) {
        try {
            console.log(`   🔄 正在尝试翻到下一页...`);
            await page.waitForTimeout(1000);
            
            // 首先检查是否存在禁用的下一页按钮（表示已到最后一页）
            const disabledNext = await page.$('.s-pagination-next.s-pagination-disabled, span.s-pagination-next[aria-disabled="true"]');
            if (disabledNext) {
                console.log(`   ✅ 检测到禁用的"Next"按钮，已到最后一页`);
                return false;
            }
            
            // 方法1: 使用标准的 class 选择器（排除禁用状态）
            let nextButton = await page.$('a.s-pagination-next:not(.s-pagination-disabled)');
            
            // 方法2: 如果方法1失败，尝试通过 aria-label 查找（必须是 <a> 标签且未禁用）
            if (!nextButton) {
                console.log(`   ℹ️  方法1失败，尝试方法2...`);
                nextButton = await page.$('a[aria-label*="Go to next page"]:not([aria-disabled="true"])');
            }
            
            // 方法3: 如果方法2失败，尝试通过文本内容查找（必须是 <a> 标签）
            if (!nextButton) {
                console.log(`   ℹ️  方法2失败，尝试方法3...`);
                nextButton = await page.$('a.s-pagination-item.s-pagination-next:has-text("Next"):not(.s-pagination-disabled)');
            }
            
            // 方法4: 如果方法3失败，尝试更宽松的选择器（必须是 <a> 标签）
            if (!nextButton) {
                console.log(`   ℹ️  方法3失败，尝试方法4...`);
                nextButton = await page.$('a.s-pagination-next[role="button"]:not([aria-disabled="true"])');
            }
            
            // 方法5: 使用 XPath 查找包含 "Next" 文本的链接（必须是 <a> 标签且未禁用）
            if (!nextButton) {
                console.log(`   ℹ️  方法4失败，尝试方法5 (XPath)...`);
                const nextButtons = await page.$$('xpath=//a[contains(@class, "s-pagination-next") and not(contains(@class, "s-pagination-disabled")) and contains(text(), "Next")]');
                if (nextButtons.length > 0) {
                    nextButton = nextButtons[0];
                }
            }
            
            if (nextButton) {
                console.log(`   ✅ 找到下一页按钮，准备点击...`);
                
                try {
                    // 滚动到按钮位置，确保可见
                    await nextButton.scrollIntoViewIfNeeded().catch(() => {});
                    await page.waitForTimeout(500);
                    
                    // 获取按钮的 href 属性（备用）
                    const href = await nextButton.getAttribute('href').catch(() => null);
                    
                    // 尝试点击
                    await nextButton.click();
                    console.log(`   ✅ 已点击下一页按钮`);
                    
                    // 等待页面加载
                    console.log(`   ⏳ 等待页面加载...`);
                    await page.waitForLoadState('load', { timeout: 15000 }).catch(() => {
                        console.log(`   ℹ️  load 超时，继续执行...`);
                    });
                    await page.waitForTimeout(2000);
                    
                    console.log(`   ✅ 翻页成功`);
                    return true;
                    
                } catch (clickError) {
                    console.log(`   ⚠️  点击失败: ${clickError.message}`);
                    
                    // 方法6: 如果点击失败，尝试通过 URL 导航
                    const href = await nextButton.getAttribute('href').catch(() => null);
                    if (href) {
                        console.log(`   ℹ️  尝试通过 URL 导航: ${href}`);
                        const currentUrl = page.url();
                        const baseUrl = new URL(currentUrl).origin;
                        const fullUrl = href.startsWith('http') ? href : `${baseUrl}${href}`;
                        
                        await page.goto(fullUrl, { waitUntil: 'load', timeout: 30000 });
                        await page.waitForTimeout(2000);
                        console.log(`   ✅ 通过 URL 导航成功`);
                        return true;
                    }
                    
                    throw clickError;
                }
            } else {
                console.log(`   ℹ️  没有找到下一页按钮（可能已到最后一页）`);
                return false;
            }
        } catch (error) {
            console.log(`   ⚠️  翻页失败: ${error.message}`);
            console.log(`   ℹ️  错误详情: ${error.stack}`);
            return false;
        }
    },

    /**
     * 处理分页爬取（支持失败重试）
     * @param {Page} page - Playwright页面对象
     * @param {Function} processPageFunction - 处理单页数据的函数，接收 (page, currentPage, totalPages) 作为参数
     * @param {Object} options - 选项 {startPage: 起始页, endPage: 结束页, maxRetries: 最大重试次数, retryDelay: 重试延迟}
     * @returns {Promise<Array>} 所有页面的爬取结果
     */
    async handlePagination(page, processPageFunction, options = {}) {
        try {
            const { 
                startPage = 1, 
                endPage = null, 
                maxRetries = 3,        // 默认最大重试 3 次
                retryDelay = 5000      // 重试前等待 5 秒
            } = options;
            
            const allResults = [];
            const failedPages = [];  // 记录失败的页面
            
            console.log(`\n   📖 开始分页爬取...`);
            console.log(`   ⚙️  重试配置: 最多重试 ${maxRetries} 次，重试延迟 ${retryDelay}ms`);
            
            // 获取初始分页信息
            let paginationInfo = await this.getPaginationInfo(page);
            let { currentPage, totalPages } = paginationInfo;
            
            console.log(`   📊 分页信息: 当前第 ${currentPage} 页，共 ${totalPages} 页`);
            
            // 如果需要从指定页开始，先跳转到指定页
            if (startPage > 1 && currentPage !== startPage) {
                console.log(`   🎯 需要跳转到第 ${startPage} 页...`);
                const targetPageLink = await page.$(`a[aria-label*="page ${startPage}"], a.s-pagination-button:has-text("${startPage}")`);
                
                if (targetPageLink) {
                    await targetPageLink.click();
                    await page.waitForLoadState('networkidle', { timeout: 15000 }).catch(() => {});
                    await page.waitForTimeout(2000);
                    paginationInfo = await this.getPaginationInfo(page);
                    currentPage = paginationInfo.currentPage;
                    console.log(`   ✅ 已跳转到第 ${currentPage} 页`);
                } else {
                    console.log(`   ⚠️  无法跳转到第 ${startPage} 页，从当前页开始`);
                }
            }
            
            // 确定结束页
            const finalPage = endPage && endPage <= totalPages ? endPage : totalPages;
            console.log(`   📌 将爬取第 ${currentPage} 页到第 ${finalPage} 页\n`);
            
            // 循环处理每一页
            while (currentPage <= finalPage) {
                console.log(`\n   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
                console.log(`   📄 正在处理第 ${currentPage}/${totalPages} 页...`);
                console.log(`   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
                
                let pageResult = null;
                let retryCount = 0;
                let pageSuccess = false;
                
                // 重试循环
                while (retryCount <= maxRetries && !pageSuccess) {
                    try {
                        if (retryCount > 0) {
                            console.log(`   🔄 第 ${retryCount} 次重试处理第 ${currentPage} 页...`);
                        }
                        
                        // 调用用户自定义的处理函数
                        pageResult = await processPageFunction(page, currentPage, totalPages);
                        pageSuccess = true;
                        
                        console.log(`\n   ✅ 第 ${currentPage} 页处理完成${retryCount > 0 ? ` (重试 ${retryCount} 次后成功)` : ''}`);
                        
                    } catch (error) {
                        retryCount++;
                        console.error(`   ❌ 第 ${currentPage} 页处理失败 (尝试 ${retryCount}/${maxRetries + 1}): ${error.message}`);
                        
                        if (retryCount <= maxRetries) {
                            console.log(`   ⏳ 等待 ${retryDelay}ms 后重试...`);
                            await page.waitForTimeout(retryDelay);
                            
                            // 尝试刷新页面
                            try {
                                console.log(`   🔄 刷新页面...`);
                                await page.reload({ waitUntil: 'load', timeout: 30000 });
                                await page.waitForTimeout(2000);
                            } catch (reloadError) {
                                console.log(`   ⚠️  页面刷新失败: ${reloadError.message}`);
                            }
                        } else {
                            console.log(`   ⚠️  第 ${currentPage} 页已达到最大重试次数，跳过该页`);
                            failedPages.push({
                                page: currentPage,
                                error: error.message,
                                retries: retryCount - 1
                            });
                        }
                    }
                }
                
                // 记录结果（无论成功或失败）
                allResults.push({
                    page: currentPage,
                    success: pageSuccess,
                    data: pageResult,
                    retries: retryCount - 1,
                    error: pageSuccess ? null : `处理失败，已重试 ${retryCount - 1} 次`
                });
                
                // 如果不是最后一页，翻到下一页
                if (currentPage < finalPage) {
                    let nextPageSuccess = false;
                    let nextRetryCount = 0;
                    
                    // 翻页也支持重试
                    while (nextRetryCount <= maxRetries && !nextPageSuccess) {
                        try {
                            if (nextRetryCount > 0) {
                                console.log(`   🔄 第 ${nextRetryCount} 次重试翻页...`);
                            }
                            
                            const hasNext = await this.goToNextPage(page);
                            
                            if (!hasNext) {
                                console.log(`   ⚠️  无法继续翻页（可能已到最后一页），停止爬取`);
                                nextPageSuccess = true;  // 标记为成功以退出重试
                                currentPage = finalPage + 1;  // 强制退出主循环
                                break;
                            }
                            
                            nextPageSuccess = true;
                            
                            // 更新分页信息
                            paginationInfo = await this.getPaginationInfo(page);
                            currentPage = paginationInfo.currentPage;
                            
                        } catch (nextError) {
                            nextRetryCount++;
                            console.error(`   ❌ 翻页失败 (尝试 ${nextRetryCount}/${maxRetries + 1}): ${nextError.message}`);
                            
                            if (nextRetryCount <= maxRetries) {
                                console.log(`   ⏳ 等待 ${retryDelay}ms 后重试翻页...`);
                                await page.waitForTimeout(retryDelay);
                            } else {
                                console.log(`   ⚠️  翻页已达到最大重试次数，停止爬取`);
                                currentPage = finalPage + 1;  // 强制退出主循环
                                break;
                            }
                        }
                    }
                } else {
                    console.log(`\n   🎉 已到达最后一页，爬取完成！`);
                    break;
                }
            }
            
            // 打印汇总信息
            const successCount = allResults.filter(r => r.success).length;
            const failedCount = allResults.filter(r => !r.success).length;
            
            console.log(`\n   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
            console.log(`   📊 分页爬取统计`);
            console.log(`   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
            console.log(`   总页数: ${allResults.length}`);
            console.log(`   成功: ${successCount} ✅`);
            console.log(`   失败: ${failedCount} ❌`);
            
            if (failedPages.length > 0) {
                console.log(`\n   失败的页面详情:`);
                failedPages.forEach(fp => {
                    console.log(`     ❌ 第 ${fp.page} 页 - ${fp.error} (重试 ${fp.retries} 次)`);
                });
            }
            console.log(`   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
            
            return allResults;
            
        } catch (error) {
            console.error(`   ❌ 分页处理致命错误: ${error.message}`);
            return [];
        }
    },

    /**
     * 提取商品图片URL
     * @param {Page} page - Playwright页面对象
     * @returns {Promise<Array<string>>} 图片URL数组
     */
    async extractImageUrls(page) {
        try {
            const imageUrls = await page.evaluate(() => {
                const urls = [];
                
                // 从主图元素提取高清图片URL
                // <img data-old-hires="https://m.media-amazon.com/images/I/71+qGfibtfL._SL1500_.jpg" id="landingImage">
                const mainImageEl = document.querySelector('#landingImage');
                
                if (mainImageEl) {
                    // 优先使用 data-old-hires（高清大图）
                    const hiresUrl = mainImageEl.getAttribute('data-old-hires');
                    if (hiresUrl) {
                        urls.push(hiresUrl);
                    } else {
                        // 备用：使用 src 属性
                        const srcUrl = mainImageEl.src;
                        if (srcUrl) {
                            urls.push(srcUrl);
                        }
                    }
                }
                
                // 未来可以在这里添加更多图片的提取逻辑
                // 例如：提取缩略图列表、商品详情图等
                
                return urls;
            });
            
            return imageUrls;
        } catch (error) {
            console.log(`         ⚠️  图片URL提取失败: ${error.message}`);
            return [];
        }
    },

    /**
     * 下载并保存图片到本地
     * @param {Array<string>} imageUrls - 图片URL数组
     * @param {string} asin - 商品ASIN
     * @param {string} itemName - 商品名称
     * @returns {Promise<Array<string>>} 保存的图片路径数组
     */
    async saveImages(imageUrls, asin, itemName) {
        try {
            if (!imageUrls || imageUrls.length === 0) {
                console.log(`         ℹ️  没有图片需要保存`);
                return [];
            }
            
            // 创建当天的图片目录（格式：images/YYYY-MM-DD/）
            const today = new Date().toISOString().split('T')[0]; // 2025-10-17
            const imagesDir = path.join(__dirname, '..', '..', 'images', today);
            
            if (!fs.existsSync(imagesDir)) {
                fs.mkdirSync(imagesDir, { recursive: true });
                console.log(`         📁 创建图片目录: images/${today}/`);
            }
            
            const savedPaths = [];
            
            for (let i = 0; i < imageUrls.length; i++) {
                const imageUrl = imageUrls[i];
                
                try {
                    console.log(`         📥 正在下载图片 ${i + 1}/${imageUrls.length}...`);
                    
                    // 下载图片
                    const response = await axios.get(imageUrl, {
                        responseType: 'arraybuffer',
                        timeout: 30000,
                        headers: {
                            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
                        }
                    });
                    
                    // 生成文件名（使用ASIN和时间戳，确保唯一性）
                    const timestamp = Date.now();
                    const ext = imageUrl.match(/\.(jpg|jpeg|png|gif|webp)/i)?.[1] || 'jpg';
                    
                    // 清理ASIN，移除路径分隔符和其他非法字符
                    const safeAsin = (asin || 'unknown').replace(/[\/\\:*?"<>|]/g, '_');
                    
                    const fileName = `${safeAsin}_${i + 1}_${timestamp}.${ext}`;
                    const filePath = path.join(imagesDir, fileName);
                    
                    // 保存图片
                    fs.writeFileSync(filePath, response.data);
                    
                    savedPaths.push(filePath);
                    console.log(`         ✅ 图片已保存: ${fileName}`);
                    
                } catch (downloadError) {
                    console.log(`         ⚠️  图片 ${i + 1} 下载失败: ${downloadError.message}`);
                }
            }
            
            console.log(`         💾 共保存 ${savedPaths.length}/${imageUrls.length} 张图片到 images/${today}/`);
            return savedPaths;
            
        } catch (error) {
            console.error(`         ❌ 图片保存过程出错: ${error.message}`);
            return [];
        }
    },

    /**
     * 提取价格信息
     * @param {Page} page - Playwright页面对象
     * @returns {Object} 价格信息 {currency, price, value, whole, fraction, rrp, discount}
     */
    async extractPriceInfo(page) {
        try {
            const priceInfo = await page.evaluate(() => {
                // ========== 提取当前价格 ==========
                // <span class="a-price-symbol">CNY</span>
                const currencyEl = document.querySelector('.a-price-symbol');
                if (!currencyEl) {
                    return null;
                }
                const currency = currencyEl.textContent.trim();
                
                // <span class="a-price-whole">370<span class="a-price-decimal">.</span></span>
                const wholeEl = document.querySelector('.a-price-whole');
                if (!wholeEl) {
                    return null;
                }
                let whole = wholeEl.textContent.trim();
                // 移除小数点
                whole = whole.replace('.', '').replace(',', '');
                
                // <span class="a-price-fraction">88</span>
                const fractionEl = document.querySelector('.a-price-fraction');
                const fraction = fractionEl ? fractionEl.textContent.trim() : '00';
                
                // 组合完整价格
                const price = `${currency}${whole}.${fraction}`;
                const priceValue = parseFloat(`${whole}.${fraction}`);
                
                // ========== 提取原价 RRP ==========
                // <span class="a-price a-text-price" data-a-strike="true"><span class="a-offscreen">CNY428.78</span></span>
                let rrp = null;
                let rrpValue = null;
                let discount = null;
                let discountPercent = null;
                
                const rrpEl = document.querySelector('.a-price.a-text-price[data-a-strike="true"] .a-offscreen');
                if (rrpEl) {
                    rrp = rrpEl.textContent.trim();  // "CNY428.78"
                    // 提取数值部分
                    const rrpMatch = rrp.match(/[\d.,]+/);
                    if (rrpMatch) {
                        rrpValue = parseFloat(rrpMatch[0].replace(',', ''));
                        
                        // 计算折扣
                        if (rrpValue > priceValue) {
                            const discountAmount = rrpValue - priceValue;
                            discountPercent = ((discountAmount / rrpValue) * 100).toFixed(0);
                            discount = `-${discountPercent}%`;
                        }
                    }
                }
                
                return {
                    currency: currency,        // 币种：CNY, EUR, USD 等
                    price: price,             // 完整价格：CNY370.88
                    value: priceValue,        // 数值：370.88
                    whole: whole,             // 整数部分：370
                    fraction: fraction,       // 小数部分：88
                    rrp: rrp,                 // 原价：CNY428.78
                    rrpValue: rrpValue,       // 原价数值：428.78
                    discount: discount,       // 折扣：-14%
                    savings: rrpValue ? (rrpValue - priceValue).toFixed(2) : null  // 节省金额：57.90
                };
            });
            
            return priceInfo;
        } catch (error) {
            console.log(`         ⚠️  价格提取失败: ${error.message}`);
            return null;
        }
    },

    /**
     * 提取评分和评论信息
     * @param {Page} page - Playwright页面对象
     * @returns {Object} 评分信息 {rating, ratingText, reviewCount, reviewText}
     */
    async extractRatingInfo(page) {
        try {
            const ratingInfo = await page.evaluate(() => {
                // 查找评分容器
                // <div id="averageCustomerReviews" data-asin="...">
                const reviewsContainer = document.querySelector('#averageCustomerReviews');
                
                if (!reviewsContainer) {
                    return null;
                }
                
                // 提取评分数值
                // <span class="a-icon-alt">4.9 out of 5 stars</span>
                const ratingAltEl = reviewsContainer.querySelector('.a-icon-alt');
                const ratingText = ratingAltEl ? ratingAltEl.textContent.trim() : null;
                
                // 从 "4.9 out of 5 stars" 提取数值 4.9
                let rating = null;
                if (ratingText) {
                    const match = ratingText.match(/([\d.]+)\s*out\s*of\s*5/i);
                    rating = match ? parseFloat(match[1]) : null;
                }
                
                // 如果上面没找到，尝试其他选择器
                if (!rating) {
                    const ratingEl = reviewsContainer.querySelector('.a-size-base.a-color-base');
                    if (ratingEl) {
                        const ratingValue = ratingEl.textContent.trim();
                        rating = parseFloat(ratingValue);
                    }
                }
                
                // 提取评论数量
                // <span id="acrCustomerReviewText" aria-label="79 Reviews">79 ratings</span>
                const reviewCountEl = reviewsContainer.querySelector('#acrCustomerReviewText');
                const reviewText = reviewCountEl ? reviewCountEl.textContent.trim() : null;
                
                // 从 "79 ratings" 提取数值 79
                let reviewCount = null;
                if (reviewText) {
                    const match = reviewText.match(/(\d+[\d,]*)/);
                    if (match) {
                        reviewCount = parseInt(match[1].replace(/,/g, ''));
                    }
                }
                
                return {
                    rating: rating,                 // 评分数值：4.9
                    ratingText: ratingText,         // 评分文本：4.9 out of 5 stars
                    reviewCount: reviewCount,       // 评论数量：79
                    reviewText: reviewText          // 评论文本：79 ratings
                };
            });
            
            return ratingInfo;
        } catch (error) {
            console.log(`         ⚠️  评分信息提取失败: ${error.message}`);
            return null;
        }
    },

    /**
     * 提取销量信息
     * @param {Page} page - Playwright页面对象
     * @returns {Object} 销量信息 {text, count, period}
     */
    async extractSalesInfo(page) {
        try {
            const salesInfo = await page.evaluate(() => {
                // 查找销量元素
                // <span id="social-proofing-faceout-title-tk_bought" class="...">
                //   <span class="a-text-bold">300+ bought</span>
                //   <span> in past month</span>
                // </span>
                
                const salesContainer = document.querySelector('#social-proofing-faceout-title-tk_bought');
                
                if (!salesContainer) {
                    return null;
                }
                
                // 获取完整文本
                const fullText = salesContainer.textContent.trim();  // "300+ bought in past month"
                
                // 提取数量部分（如 "300+"）
                const countMatch = fullText.match(/(\d+[\+k]?)\s*bought/i);
                const count = countMatch ? countMatch[1] : null;
                
                // 提取时间周期（如 "past month"）
                const periodMatch = fullText.match(/in\s+(.+)/i);
                const period = periodMatch ? periodMatch[1].trim() : null;
                
                return {
                    fullText: fullText,        // 完整文本：300+ bought in past month
                    count: count,              // 数量：300+
                    period: period,            // 周期：past month
                    raw: salesContainer.innerHTML  // 原始HTML
                };
            });
            
            return salesInfo;
        } catch (error) {
            console.log(`         ⚠️  销量信息提取失败: ${error.message}`);
            return null;
        }
    },

    /**
     * 爬取评论数据
     * @param {Page} page - Playwright页面对象
     * @param {Object} options - 选项 {crawlAllReviews: 是否爬取全部评论}
     * @returns {Object} 评论数据 {hasMoreReviewsLink, seeAllReviewsUrl, reviews}
     */
    async crawlReviews(page, options = {}) {
        try {
            console.log(`         📝 开始爬取评论...`);
            
            const { crawlAllReviews = false } = options;
            
            // 1. 检测"See more reviews"链接是否存在
            const seeAllReviewsLink = await page.$('a[data-hook="see-all-reviews-link-foot"]');
            const hasMoreReviewsLink = !!seeAllReviewsLink;
            let seeAllReviewsUrl = null;
            
            if (hasMoreReviewsLink) {
                seeAllReviewsUrl = await seeAllReviewsLink.getAttribute('href');
                console.log(`         ✅ 找到"See more reviews"链接: ${seeAllReviewsUrl}`);
            } else {
                console.log(`         ℹ️  未找到"See more reviews"链接`);
            }
            
            // 2. 如果配置为爬取全部评论且存在链接
            if (crawlAllReviews && hasMoreReviewsLink) {
                console.log(`         🔄 将来会点击进入全部评论页面（功能待完成）`);
                // TODO: 未来实现点击进入全部评论页面并爬取
                return {
                    hasMoreReviewsLink: true,
                    seeAllReviewsUrl: seeAllReviewsUrl,
                    crawlAllReviews: true,
                    status: 'pending',
                    message: '全部评论爬取功能待完成'
                };
            }
            
            // 3. 从当前页面爬取评论（默认行为）
            console.log(`         📋 从当前页面提取评论...`);
            
            const reviews = await page.evaluate(() => {
                const reviewsList = [];
                const reviewContainer = document.querySelector('#cm-cr-dp-review-list');
                
                if (!reviewContainer) {
                    return [];
                }
                
                const reviewItems = reviewContainer.querySelectorAll('li[data-hook="review"]');
                
                reviewItems.forEach((reviewItem, index) => {
                    try {
                        // 评论ID
                        const reviewId = reviewItem.id || `review-${index}`;
                        
                        // 用户名
                        const profileNameEl = reviewItem.querySelector('.a-profile-name');
                        const authorName = profileNameEl ? profileNameEl.textContent.trim() : '';
                        
                        // 评分
                        const ratingEl = reviewItem.querySelector('[data-hook="review-star-rating"] .a-icon-alt');
                        const ratingText = ratingEl ? ratingEl.textContent.trim() : '';
                        const ratingMatch = ratingText.match(/([\d.]+)\s*out\s*of\s*5/i);
                        const rating = ratingMatch ? parseFloat(ratingMatch[1]) : null;
                        
                        // 评论标题
                        const titleEl = reviewItem.querySelector('[data-hook="review-title"]');
                        let title = '';
                        if (titleEl) {
                            // 优先获取原始内容（.cr-original-review-content）
                            const originalTitleEl = titleEl.querySelector('.cr-original-review-content');
                            title = originalTitleEl ? originalTitleEl.textContent.trim() : titleEl.textContent.trim();
                            // 移除评分文本
                            title = title.replace(/[\d.]+\s*out\s*of\s*5\s*stars/i, '').trim();
                        }
                        
                        // 评论日期
                        const dateEl = reviewItem.querySelector('[data-hook="review-date"]');
                        const reviewDate = dateEl ? dateEl.textContent.trim() : '';
                        
                        // 评论内容
                        const bodyEl = reviewItem.querySelector('[data-hook="review-body"]');
                        let reviewBody = '';
                        if (bodyEl) {
                            // 优先获取原始内容（.cr-original-review-content）
                            const originalBodyEl = bodyEl.querySelector('.cr-original-review-content');
                            reviewBody = originalBodyEl ? originalBodyEl.textContent.trim() : bodyEl.textContent.trim();
                        }
                        
                        // 有帮助的人数
                        const helpfulEl = reviewItem.querySelector('[data-hook="helpful-vote-statement"]');
                        const helpfulText = helpfulEl ? helpfulEl.textContent.trim() : '';
                        const helpfulMatch = helpfulText.match(/(\d+)/);
                        const helpfulCount = helpfulMatch ? parseInt(helpfulMatch[1]) : 0;
                        
                        // 是否是验证购买
                        const verifiedEl = reviewItem.querySelector('[data-hook="avp-badge-linkless"]');
                        const isVerifiedPurchase = !!verifiedEl;
                        
                        // Flavor Name / Size等变体信息
                        const formatStripEl = reviewItem.querySelector('[data-hook="format-strip-linkless"]');
                        const variantInfo = formatStripEl ? formatStripEl.textContent.trim() : '';
                        
                        reviewsList.push({
                            reviewId: reviewId,
                            author: authorName,
                            rating: rating,
                            ratingText: ratingText,
                            title: title,
                            date: reviewDate,
                            body: reviewBody,
                            helpfulCount: helpfulCount,
                            helpfulText: helpfulText,
                            isVerifiedPurchase: isVerifiedPurchase,
                            variantInfo: variantInfo
                        });
                    } catch (err) {
                        console.error('提取单个评论时出错:', err.message);
                    }
                });
                
                return reviewsList;
            });
            
            console.log(`         ✅ 成功提取 ${reviews.length} 条评论`);
            
            // 打印前3条评论的摘要
            if (reviews.length > 0) {
                const previewCount = Math.min(3, reviews.length);
                console.log(`         📄 评论预览（前${previewCount}条）:`);
                for (let i = 0; i < previewCount; i++) {
                    const review = reviews[i];
                    console.log(`            ${i + 1}. ${review.author} - ${review.rating}⭐ - ${review.title.substring(0, 30)}...`);
                }
            }
            
            return {
                hasMoreReviewsLink: hasMoreReviewsLink,
                seeAllReviewsUrl: seeAllReviewsUrl,
                crawlAllReviews: crawlAllReviews,
                reviewCount: reviews.length,
                reviews: reviews
            };
            
        } catch (error) {
            console.log(`         ⚠️  评论爬取失败: ${error.message}`);
            return {
                hasMoreReviewsLink: false,
                seeAllReviewsUrl: null,
                crawlAllReviews: false,
                reviewCount: 0,
                reviews: [],
                error: error.message
            };
        }
    },

    /**
     * 保存评论到数据库
     * @param {Array} reviews - 评论数组
     * @param {Object} context - 上下文信息 {asin, productTitle, productUrl, taskName, batchId, searchKeyword, projectIndex, itemIndex}
     * @returns {Promise<Object>} 保存结果 {saved, skipped, failed}
     */
    async saveReviewsToDatabase(reviews, context = {}) {
        try {
            if (!reviews || reviews.length === 0) {
                console.log(`         ℹ️  没有评论需要保存`);
                return { saved: 0, skipped: 0, failed: 0 };
            }
            
            console.log(`         💾 开始保存 ${reviews.length} 条评论到数据库...`);
            
            const {
                asin = null,
                productTitle = null,
                productUrl = null,
                taskName = this.name || 'amazon-jp',
                batchId = null,
                searchKeyword = null,
                projectIndex = null,
                itemIndex = null
            } = context;
            
            let saved = 0;
            let skipped = 0;
            let failed = 0;
            
            for (const review of reviews) {
                try {
                    // 解析评论日期
                    let parsedDate = null;
                    if (review.date) {
                        try {
                            const dateMatch = review.date.match(/(\w+\s+\d+,\s+\d{4})/);
                            if (dateMatch) {
                                parsedDate = new Date(dateMatch[1]);
                            }
                        } catch (dateError) {
                            // 日期解析失败不影响保存
                        }
                    }
                    
                    // 准备要保存的评论文档
                    const reviewDoc = {
                        reviewId: review.reviewId,
                        taskName: taskName,
                        asin: asin,
                        productTitle: productTitle,
                        productUrl: productUrl,
                        author: review.author,
                        rating: review.rating,
                        ratingText: review.ratingText,
                        title: review.title,
                        body: review.body,
                        date: review.date,
                        parsedDate: parsedDate,
                        helpfulCount: review.helpfulCount || 0,
                        helpfulText: review.helpfulText,
                        isVerifiedPurchase: review.isVerifiedPurchase || false,
                        variantInfo: review.variantInfo,
                        crawlTimestamp: new Date(),
                        batchId: batchId,
                        searchKeyword: searchKeyword,
                        projectIndex: projectIndex,
                        itemIndex: itemIndex,
                        metadata: {
                            crawledAt: new Date().toISOString()
                        }
                    };
                    
                    // 使用 upsert 避免重复（基于 reviewId）
                    await Review.findOneAndUpdate(
                        { reviewId: review.reviewId },
                        { $set: reviewDoc },
                        { upsert: true, new: true }
                    );
                    
                    saved++;
                    
                } catch (error) {
                    if (error.code === 11000) {
                        // 重复键错误，跳过
                        skipped++;
                    } else {
                        console.error(`         ⚠️  保存评论失败 (${review.reviewId}): ${error.message}`);
                        failed++;
                    }
                }
            }
            
            console.log(`         ✅ 评论保存完成: 成功 ${saved} 条, 跳过 ${skipped} 条, 失败 ${failed} 条`);
            
            return { saved, skipped, failed };
            
        } catch (error) {
            console.error(`         ❌ 保存评论到数据库时出错: ${error.message}`);
            return { saved: 0, skipped: 0, failed: 0, error: error.message };
        }
    },

    /**
     * 处理单个 item 的数据
     * @param {Page} detailPage - 详情页的 Page 对象
     * @param {Object} itemInfo - item 信息 {index, asin, name, selected}
     * @param {number} projectIndex - 项目索引
     * @returns {Object} 处理结果
     */
    async processItemData(detailPage, itemInfo, projectIndex) {
        try {
            console.log(`         🔹 正在处理 item ${itemInfo.index}: "${itemInfo.name}" (ASIN: ${itemInfo.asin})...`);
            
            // ============================================
            // 👇 在这里编写处理单个 item 数据的逻辑
            // ============================================
            
            // 等待一段时间（确保页面加载）
            await detailPage.waitForTimeout(1000);
            
            // 获取商品标题
            const title = await detailPage.$eval('#productTitle', el => el.textContent.trim()).catch(() => '');
            console.log(`         ✅ 商品标题: ${title}`);
            
            // 获取价格信息
            const priceInfo = await this.extractPriceInfo(detailPage);
            if (priceInfo) {
                console.log(`         💰 价格: ${priceInfo.price}`);
                if (priceInfo.rrp) {
                    console.log(`         🏷️  原价: ${priceInfo.rrp} (折扣: ${priceInfo.discount}, 节省: ${priceInfo.currency}${priceInfo.savings})`);
                }
            } else {
                console.log(`         ⚠️  未找到价格信息`);
            }
            
            // 获取评分信息
            const ratingInfo = await this.extractRatingInfo(detailPage);
            if (ratingInfo) {
                console.log(`         ⭐ 评分: ${ratingInfo.rating}/5 (${ratingInfo.reviewCount} 条评论)`);
            } else {
                console.log(`         ℹ️  未找到评分信息`);
            }
            
            // 获取销量信息
            const salesInfo = await this.extractSalesInfo(detailPage);
            if (salesInfo) {
                console.log(`         📊 销量: ${salesInfo.fullText}`);
            } else {
                console.log(`         ℹ️  未找到销量信息`);
            }
            
            // 爬取评论数据
            // 可以通过修改 crawlAllReviews 参数控制是否爬取全部评论
            // crawlAllReviews: false - 只爬取当前页面评论（默认）
            // crawlAllReviews: true - 爬取全部评论（功能待完成）
            const reviewsData = await this.crawlReviews(detailPage, { 
                crawlAllReviews: false  // 👈 修改此参数来控制是否爬取全部评论
            });
            
            // 获取当前页面URL
            const currentUrl = detailPage.url();
            
            // 保存评论到数据库（每条评论单独保存）
            let reviewsSaveResult = null;
            if (reviewsData && reviewsData.reviews && reviewsData.reviews.length > 0) {
                // 获取搜索关键词
                let searchKeyword = process.env.CRAWL_KEYWORD;
                if (!searchKeyword) {
                    const config = require('../../tasks.config');
                    const keywords = config.keywords && config.keywords['amazon-jp'];
                    searchKeyword = (keywords && keywords.length > 0) ? keywords[0] : null;
                }
                
                reviewsSaveResult = await this.saveReviewsToDatabase(reviewsData.reviews, {
                    asin: itemInfo.asin,
                    productTitle: title,
                    productUrl: currentUrl,
                    taskName: this.name,
                    batchId: null,  // 可以传入批次ID
                    searchKeyword: searchKeyword,
                    projectIndex: projectIndex,
                    itemIndex: itemInfo.index
                });
            }
            
            // 提取并保存图片
            // const imageUrls = await this.extractImageUrls(detailPage);
            // console.log(`         🖼️  找到 ${imageUrls.length} 张图片`);
            
            // const savedImagePaths = await this.saveImages(imageUrls, itemInfo.asin, itemInfo.name);
            
            const result = {
                projectIndex: projectIndex,
                itemIndex: itemInfo.index,
                asin: itemInfo.asin,
                name: itemInfo.name,
                title: title,
                url: currentUrl,
                // 价格信息
                price: priceInfo ? {
                    currency: priceInfo.currency,    // 币种（如 CNY, EUR, USD）
                    price: priceInfo.price,          // 完整价格字符串（如 "CNY370.88"）
                    value: priceInfo.value,          // 数值（如 370.88）
                    whole: priceInfo.whole,          // 整数部分（如 "370"）
                    fraction: priceInfo.fraction,    // 小数部分（如 "88"）
                    rrp: priceInfo.rrp,              // 原价（如 "CNY428.78"）
                    rrpValue: priceInfo.rrpValue,    // 原价数值（如 428.78）
                    discount: priceInfo.discount,    // 折扣百分比（如 "-14%"）
                    savings: priceInfo.savings       // 节省金额（如 "57.90"）
                } : null,
                // 评分信息
                rating: ratingInfo ? {
                    rating: ratingInfo.rating,           // 评分数值（如 4.9）
                    ratingText: ratingInfo.ratingText,   // 评分文本（如 "4.9 out of 5 stars"）
                    reviewCount: ratingInfo.reviewCount, // 评论数量（如 79）
                    reviewText: ratingInfo.reviewText    // 评论文本（如 "79 ratings"）
                } : null,
                // 销量信息
                sales: salesInfo ? {
                    fullText: salesInfo.fullText,    // 完整文本（如 "300+ bought in past month"）
                    count: salesInfo.count,          // 销量数量（如 "300+"）
                    period: salesInfo.period         // 时间周期（如 "past month"）
                } : null,
                // 评论信息
                reviews: reviewsData ? {
                    hasMoreReviewsLink: reviewsData.hasMoreReviewsLink,  // 是否有"查看全部评论"链接
                    seeAllReviewsUrl: reviewsData.seeAllReviewsUrl,      // 全部评论页面URL
                    crawlAllReviews: reviewsData.crawlAllReviews,        // 是否配置为爬取全部
                    reviewCount: reviewsData.reviewCount,                // 当前提取的评论数量
                    reviews: reviewsData.reviews,                        // 评论详情数组（完整数据）
                    status: reviewsData.status,                          // 状态（如果是待完成功能）
                    message: reviewsData.message,                        // 消息（如果是待完成功能）
                    error: reviewsData.error,                            // 错误信息（如果有）
                    // 数据库保存结果
                    dbSaveResult: reviewsSaveResult ? {
                        saved: reviewsSaveResult.saved,                  // 成功保存到数据库的数量
                        skipped: reviewsSaveResult.skipped,              // 跳过的数量（重复）
                        failed: reviewsSaveResult.failed,                // 失败的数量
                        error: reviewsSaveResult.error                   // 保存错误信息
                    } : null
                } : null,
                // 图片信息
                // images: {
                //     urls: imageUrls,                     // 图片URL数组
                //     count: imageUrls.length,             // 图片数量
                //     savedPaths: savedImagePaths,         // 本地保存路径
                //     savedCount: savedImagePaths.length   // 成功保存的数量
                // },
                timestamp: new Date().toISOString()
            };
            
            // 保存结果到数据库
            try {
                await this.saveToDatabase(result);
            } catch (dbError) {
                console.log(`         ⚠️  保存到数据库失败: ${dbError.message}`);
            }
            
            // ============================================
            // 👆 在上方编写处理单个 item 数据的逻辑
            // ============================================
            
            console.log(`         ✅ item ${itemInfo.index} "${itemInfo.name}" 处理完成`);
            return result;
            
        } catch (error) {
            console.error(`         ❌ 处理 item ${itemInfo.index} 失败: ${error.message}`);
            return { 
                projectIndex: projectIndex,
                itemIndex: itemInfo.index, 
                asin: itemInfo.asin,
                error: error.message 
            };
        }
    },

    /**
     * 处理单个项目详情页
     * @param {Page} detailPage - 项目详情页的 Page 对象
     * @param {number} itemIndex - 项目索引
     * @returns {Object} 处理结果
     */
    async processProjectDetail(detailPage, itemIndex) {
        try {
            console.log(`       🔍 正在处理第 ${itemIndex} 个项目详情...`);
            
            // 等待页面加载
            await detailPage.waitForTimeout(3000);
            
            // 获取页面基本信息
            const title = await detailPage.title();
            const url = detailPage.url();
            
            // 查找 id="tp-inline-twister-dim-values-container" 下的 ul
            const container = await detailPage.$('#tp-inline-twister-dim-values-container');
            
            let items = [];
            let selectedItem = null;
            
            if (!container) {
                console.log(`       ℹ️  未找到容器 #tp-inline-twister-dim-values-container`);
            } else {
                // 获取容器下的 ul
                const ul = await container.$('ul');
                
                if (!ul) {
                    console.log(`       ℹ️  容器内未找到 ul 元素`);
                } else {
                    // 获取所有 li 元素
                    const liElements = await ul.$$('li');
                    const liCount = liElements.length;
                    
                    console.log(`       📋 识别了 ${liCount} 个 li 元素`);
                    
                    // 遍历每个 li，提取信息
                    for (let i = 0; i < liElements.length; i++) {
                        const li = liElements[i];
                        
                        // 获取 data-asin 属性
                        const asin = await li.getAttribute('data-asin');
                        
                        // 获取图片的 alt 属性作为名称
                        const imgAlt = await li.$eval('img', img => img.alt).catch(() => '');
                        
                        // 检查是否选中：查找 class 包含 "a-button-selected" 的 span
                        const selectedSpan = await li.$('span.a-button-selected');
                        const isSelected = !!selectedSpan;
                        
                        const itemInfo = {
                            index: i + 1,
                            asin: asin,
                            name: imgAlt,
                            selected: isSelected
                        };
                        
                        items.push(itemInfo);
                        
                        if (isSelected) {
                            selectedItem = itemInfo;
                            console.log(`       ✅ Li ${i + 1}: ASIN=${asin}, Name="${imgAlt}" [选中]`);
                        } else {
                            console.log(`       - Li ${i + 1}: ASIN=${asin}, Name="${imgAlt}"`);
                        }
                    }
                    
                    if (selectedItem) {
                        console.log(`       ⭐ 当前选中的 item: "${selectedItem.name}" (ASIN: ${selectedItem.asin})`);
                    } else {
                        console.log(`       ℹ️  未检测到选中的 item`);
                    }
                }
            }
            
            // 处理所有 items
            const itemResults = [];
            
            if (items.length === 0) {
                // item 数为 0，表示只有一个需要处理（无需切换）
                console.log(`       📌 无 item 列表，处理当前页面...`);
                const singleItemResult = await this.processItemData(detailPage, {
                    index: 1,
                    asin: 'N/A',
                    name: '默认项',
                    selected: true
                }, itemIndex);
                itemResults.push(singleItemResult);
            } else {
                // 有多个 items，循环处理每一个
                console.log(`\n       🔄 开始循环处理 ${items.length} 个 items...\n`);
                
                for (let i = 0; i < items.length; i++) {
                    const item = items[i];
                    console.log(`       📍 [${i + 1}/${items.length}] 切换到 item: "${item.name}"`);
                    
                    try {
                        // 如果不是当前选中的item，需要点击切换
                        if (!item.selected) {
                            // 重新获取容器和li元素（避免元素失效）
                            const currentContainer = await detailPage.$('#tp-inline-twister-dim-values-container');
                            if (currentContainer) {
                                const currentUl = await currentContainer.$('ul');
                                if (currentUl) {
                                    const currentLiElements = await currentUl.$$('li');
                                    const targetLi = currentLiElements[i];
                                    
                                    if (targetLi) {
                                        // 点击 li 中的 span 按钮进行切换
                                        const button = await targetLi.$('span.a-button-toggle');
                                        if (button) {
                                            console.log(`         👆 点击切换到 item ${i + 1}...`);
                                            await button.click();
                                            await detailPage.waitForTimeout(2000); // 等待页面更新
                                        }
                                    }
                                }
                            }
                        } else {
                            console.log(`         ✓ 当前已选中此 item，无需切换`);
                        }
                        
                        // 处理当前 item 的数据
                        const itemResult = await this.processItemData(detailPage, item, itemIndex);
                        itemResults.push(itemResult);
                        
                    } catch (itemError) {
                        console.error(`         ❌ 处理 item ${i + 1} 时出错: ${itemError.message}`);
                        itemResults.push({
                            projectIndex: itemIndex,
                            itemIndex: i + 1,
                            asin: item.asin,
                            error: itemError.message
                        });
                    }
                }
                
                console.log(`\n       ✅ 所有 items 处理完成\n`);
            }
            
            const result = {
                itemIndex: itemIndex,
                title: title,
                url: url,
                itemCount: items.length,
                items: items,
                selectedItem: selectedItem,
                itemResults: itemResults,
                timestamp: new Date().toISOString()
            };
            
            console.log(`       ✅ 第 ${itemIndex} 个项目处理完成 (${items.length} 个 item，已处理 ${itemResults.length} 个)`);
            return result;
            
        } catch (error) {
            console.error(`       ❌ 处理第 ${itemIndex} 个项目失败: ${error.message}`);
            return { itemIndex, error: error.message };
        }
    },

    /**
     * 处理单页项目数据（读取所有 listitem，点击打开详情页处理后返回）
     * @param {Page} page - Playwright页面对象
     * @param {number} currentPage - 当前页码
     * @param {number} totalPages - 总页数
     * @returns {Object} 当前页的数据
     */
    async processSinglePage(page, currentPage, totalPages) {
        try {
            console.log(`   📦 正在处理第 ${currentPage}/${totalPages} 页的数据...`);
            
            // 获取所有 role="listitem" 的元素
            const listItems = await page.$$('[role="listitem"]');
            console.log(`   📋 找到 ${listItems.length} 个项目`);
            
            const pageResults = [];
            
            // 逐个处理每个 listitem
            for (let i = 0; i < listItems.length; i++) {
                console.log(`\n   📦 [${i + 1}/${listItems.length}] 准备处理项目...`);
                
                try {
                    // 重新获取当前页面的 listitem（因为页面可能刷新）
                    const currentListItems = await page.$$('[role="listitem"]');
                    const currentItem = currentListItems[i];
                    
                    if (!currentItem) {
                        console.log(`   ⚠️  第 ${i + 1} 个项目元素未找到，跳过`);
                        continue;
                    }
                    
                    // 查找可点击的链接
                    const link = await currentItem.$('a[href]');
                    
                    if (!link) {
                        console.log(`   ⚠️  第 ${i + 1} 个项目没有可点击的链接，跳过`);
                        continue;
                    }
                    
                    // 获取链接地址（用于调试）
                    // const href = await link.getAttribute('href');
                    // console.log(`   🔗 项目链接: ${href}`);
                    
                    // 获取浏览器上下文，准备处理新标签
                    const context = page.context();
                    const originalPage = page; // 保存原页面引用
                    
                    // 点击链接打开详情页（会在新标签打开）
                    console.log(`   👆 点击打开详情页（新标签）...`);
                    
                    // 监听新标签页的打开
                    const [newPage] = await Promise.all([
                        context.waitForEvent('page'),
                        link.click()
                    ]);
                    
                    // 等待新标签页加载完成
                    console.log(`   ⏳ 等待详情页加载...`);
                    await newPage.waitForLoadState('load', { timeout: 30000 }).catch(() => {
                        console.log(`   ⚠️  load 事件超时`);
                    });
                    
                    // 等待关键元素加载（更可靠）
                    await newPage.waitForSelector('#productTitle, h1', { timeout: 10000 }).catch(() => {
                        console.log(`   ⚠️  商品标题元素加载超时`);
                    });
                    
                    // 额外等待确保页面稳定
                    await newPage.waitForTimeout(2000);
                    console.log(`   ✅ 详情页加载完成`);
                    
                    // 处理项目详情页（在新标签中）
                    const itemResult = await this.processProjectDetail(newPage, i + 1);
                    pageResults.push(itemResult);
                    
                    // 关闭新标签页
                    console.log(`   🔄 关闭详情页标签...`);
                    await newPage.close();
                    
                    // 切换回原页面（列表页）
                    console.log(`   ↩️  已切换回列表页`);
                    await originalPage.waitForTimeout(500);
                    console.log(`   ✅ 已返回列表页`);
                    
                    // 等待一小段时间再处理下一个
                    await page.waitForTimeout(500);
                    
                } catch (error) {
                    console.error(`   ❌ 处理第 ${i + 1} 个项目时出错: ${error.message}`);
                    pageResults.push({ 
                        itemIndex: i + 1, 
                        error: error.message 
                    });
                    
                    // 尝试关闭可能打开的新标签页
                    try {
                        const context = page.context();
                        const pages = context.pages();
                        // 如果有多个页面，关闭最后一个（通常是新打开的）
                        if (pages.length > 1) {
                            console.log(`   🔄 关闭可能存在的详情页标签...`);
                            await pages[pages.length - 1].close();
                            await page.waitForTimeout(500);
                        }
                    } catch (closeError) {
                        console.error(`   ⚠️  关闭标签页时出错: ${closeError.message}`);
                    }
                }
            }
            
            const result = {
                page: currentPage,
                totalItems: listItems.length,
                processedItems: pageResults.length,
                items: pageResults,
                timestamp: new Date().toISOString()
            };
            
            console.log(`\n   ✅ 第 ${currentPage} 页所有项目处理完成 (${pageResults.length}/${listItems.length})`);
            return result;
            
        } catch (error) {
            console.error(`   ❌ 处理第 ${currentPage} 页失败: ${error.message}`);
            return { error: error.message };
        }
    },

    /**
     * 搜索商品（可选的辅助方法）
     * @param {Page} page - Playwright页面对象
     * @param {string} keyword - 搜索关键词
     */
    async searchProducts(page, keyword) {
        try {
            console.log(`   搜索关键词: ${keyword}`);
            
            // 输入搜索关键词
            await page.fill(this.search.selectors.searchInput, keyword);
            
            // 点击搜索按钮
            await page.click(this.search.selectors.searchButton);
            
            // 等待搜索结果加载
            await page.waitForSelector(this.selectors.productList, { timeout: 10000 });
            await page.waitForTimeout(2000);
            
            // 提取商品信息
            const products = await page.$$eval(this.selectors.productList, (items, selectors) => {
                return items.slice(0, 20).map(item => {
                    const titleEl = item.querySelector('h2 .a-link-normal');
                    const priceEl = item.querySelector('.a-price-whole');
                    const imageEl = item.querySelector('.s-image');
                    const ratingEl = item.querySelector('.a-icon-star-small');
                    
                    return {
                        title: titleEl?.textContent?.trim() || '',
                        price: priceEl?.textContent?.trim() || '',
                        imageUrl: imageEl?.src || '',
                        productUrl: titleEl?.href || '',
                        rating: ratingEl?.getAttribute('aria-label') || ''
                    };
                }).filter(product => product.title);
            }, this.selectors);
            
            console.log(`   找到 ${products.length} 个商品`);
            
            return products;
        } catch (error) {
            console.error(`   搜索失败:`, error.message);
            return [];
        }
    },

    /**
     * 保存结果到数据库
     * @param {Object} data - 要保存的数据
     * @returns {Promise<Object>} 保存的文档
     */
    async saveToDatabase(data) {
        try {
            // 检查数据库连接是否激活
            if (!dbConnection.isConnectionActive()) {
                console.log(`         ℹ️  数据库未连接，跳过保存`);
                return null;
            }
            
            // 获取搜索关键字（从环境变量）
            const searchKeyword = process.env.CRAWL_KEYWORD || null;
            
            // 准备文档数据
            const document = {
                taskName: this.name,
                success: !data.error,
                url: data.url,
                title: data.title,
                data: {
                    projectIndex: data.projectIndex,
                    itemIndex: data.itemIndex,
                    asin: data.asin,
                    name: data.name,
                    // 可以添加更多字段
                    ...data
                },
                error: data.error || null,
                crawlTimestamp: data.timestamp ? new Date(data.timestamp) : new Date(),
                batchId: `item_${Date.now()}`,
                executionMode: 'custom',
                searchKeyword: searchKeyword,  // 保存搜索关键字
                metadata: {
                    source: 'amazon-de',
                    savedAt: new Date(),
                    itemType: 'product_detail',
                    searchKeyword: searchKeyword  // 也在 metadata 中保存一份（向后兼容）
                }
            };
            
            // 保存到数据库
            const savedDoc = await CrawlResult.create(document);
            const keywordInfo = searchKeyword ? `, 关键字: ${searchKeyword}` : '';
            console.log(`         💾 已保存到数据库 (ID: ${savedDoc._id}${keywordInfo})`);
            
            return savedDoc;
            
        } catch (error) {
            console.error(`         ❌ 数据库保存失败: ${error.message}`);
            throw error;
        }
    }
};

